/**
 * 游戏工具函数
 * 包含常用的工具函数和辅助方法
 */

import { GAME_CONSTANTS, COLORS, ERROR_MESSAGES, SUCCESS_MESSAGES } from './constants.js';

/**
 * 数学工具函数
 */
export const MathUtils = {
    /**
     * 计算两点之间的距离
     * @param {number} x1 
     * @param {number} y1 
     * @param {number} x2 
     * @param {number} y2 
     * @returns {number}
     */
    distance(x1, y1, x2, y2) {
        return Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2);
    },

    /**
     * 将数值限制在指定范围内
     * @param {number} value 
     * @param {number} min 
     * @param {number} max 
     * @returns {number}
     */
    clamp(value, min, max) {
        return Math.min(Math.max(value, min), max);
    },

    /**
     * 线性插值
     * @param {number} start 
     * @param {number} end 
     * @param {number} t 
     * @returns {number}
     */
    lerp(start, end, t) {
        return start + (end - start) * t;
    },

    /**
     * 生成指定范围内的随机整数
     * @param {number} min 
     * @param {number} max 
     * @returns {number}
     */
    randomInt(min, max) {
        return Math.floor(Math.random() * (max - min + 1)) + min;
    },

    /**
     * 生成指定范围内的随机浮点数
     * @param {number} min 
     * @param {number} max 
     * @returns {number}
     */
    randomFloat(min, max) {
        return Math.random() * (max - min) + min;
    },

    /**
     * 根据概率返回布尔值
     * @param {number} probability 0-1之间的概率
     * @returns {boolean}
     */
    chance(probability) {
        return Math.random() < probability;
    }
};

/**
 * DOM工具函数
 */
export const DOMUtils = {
    /**
     * 安全获取DOM元素
     * @param {string} selector 
     * @returns {HTMLElement|null}
     */
    getElement(selector) {
        try {
            return document.querySelector(selector);
        } catch (error) {
            console.warn(`无法找到元素: ${selector}`, error);
            return null;
        }
    },

    /**
     * 安全获取多个DOM元素
     * @param {string} selector 
     * @returns {NodeList}
     */
    getElements(selector) {
        try {
            return document.querySelectorAll(selector);
        } catch (error) {
            console.warn(`无法找到元素: ${selector}`, error);
            return [];
        }
    },

    /**
     * 切换元素的显示/隐藏状态
     * @param {HTMLElement} element 
     * @param {boolean} show 
     */
    toggleVisibility(element, show) {
        if (!element) return;
        if (show) {
            element.classList.remove('hidden');
        } else {
            element.classList.add('hidden');
        }
    },

    /**
     * 设置元素的样式
     * @param {HTMLElement} element 
     * @param {object} styles 
     */
    setStyles(element, styles) {
        if (!element) return;
        Object.assign(element.style, styles);
    }
};

/**
 * 游戏逻辑工具函数
 */
export const GameUtils = {
    /**
     * 检查坐标是否在地图范围内
     * @param {number} x 
     * @param {number} y 
     * @param {number} mapWidth 
     * @param {number} mapHeight 
     * @returns {boolean}
     */
    isInMapBounds(x, y, mapWidth, mapHeight) {
        return x >= 0 && x < mapWidth && y >= 0 && y < mapHeight;
    },

    /**
     * 将像素坐标转换为瓦片坐标
     * @param {number} pixelPos 
     * @returns {number}
     */
    pixelToTile(pixelPos) {
        return Math.floor(pixelPos / GAME_CONSTANTS.TILE_SIZE);
    },

    /**
     * 将瓦片坐标转换为像素坐标
     * @param {number} tilePos 
     * @returns {number}
     */
    tileToPixel(tilePos) {
        return tilePos * GAME_CONSTANTS.TILE_SIZE;
    },

    /**
     * 检查两个矩形是否碰撞
     * @param {object} rect1 
     * @param {object} rect2 
     * @returns {boolean}
     */
    checkRectCollision(rect1, rect2) {
        return rect1.x < rect2.x + rect2.width &&
               rect1.x + rect1.width > rect2.x &&
               rect1.y < rect2.y + rect2.height &&
               rect1.y + rect1.height > rect2.y;
    },

    /**
     * 计算等级所需的经验值
     * @param {number} level 
     * @returns {number}
     */
    calculateExpForLevel(level) {
        return Math.floor(100 * Math.pow(1.2, level - 1));
    },

    /**
     * 根据等级缩放属性值
     * @param {number} baseValue 
     * @param {number} level 
     * @param {number} scalingFactor 
     * @returns {number}
     */
    scaleValueByLevel(baseValue, level, scalingFactor = 0.1) {
        return Math.floor(baseValue * (1 + (level - 1) * scalingFactor));
    },

    /**
     * 生成随机掉落物品
     * @param {array} itemPool 
     * @param {number} dropRate 
     * @returns {object|null}
     */
    generateRandomDrop(itemPool, dropRate = 0.5) {
        if (!MathUtils.chance(dropRate) || !itemPool.length) {
            return null;
        }
        return itemPool[MathUtils.randomInt(0, itemPool.length - 1)];
    }
};

/**
 * 动画工具函数
 */
export const AnimationUtils = {
    /**
     * 创建缓动函数
     * @param {string} type 
     * @returns {function}
     */
    easing(type) {
        const easings = {
            linear: t => t,
            easeIn: t => t * t,
            easeOut: t => t * (2 - t),
            easeInOut: t => t < 0.5 ? 2 * t * t : -1 + (4 - 2 * t) * t
        };
        return easings[type] || easings.linear;
    },

    /**
     * 平滑过渡数值
     * @param {number} current 
     * @param {number} target 
     * @param {number} speed 
     * @returns {number}
     */
    smoothTransition(current, target, speed = 0.1) {
        return MathUtils.lerp(current, target, speed);
    }
};

/**
 * 通知系统
 */
export const NotificationUtils = {
    /**
     * 显示游戏通知
     * @param {string} message 
     * @param {string} type 
     * @param {number} duration 
     */
    showNotification(message, type = 'info', duration = GAME_CONSTANTS.NOTIFICATION_DURATION) {
        const notification = document.createElement('div');
        notification.className = `game-notification notification-${type}`;
        notification.textContent = message;
        
        const colors = {
            success: COLORS.SUCCESS,
            warning: COLORS.WARNING,
            error: COLORS.DANGER,
            info: COLORS.INFO
        };
        
        DOMUtils.setStyles(notification, {
            position: 'fixed',
            top: '20%',
            left: '50%',
            transform: 'translate(-50%, -50%)',
            background: `rgba(${this.hexToRgb(colors[type] || colors.info)}, 0.9)`,
            color: 'white',
            padding: '15px 25px',
            borderRadius: '8px',
            fontSize: '16px',
            fontWeight: 'bold',
            zIndex: GAME_CONSTANTS.NOTIFICATION_Z_INDEX,
            animation: 'notificationFadeInOut 2s ease-in-out'
        });
        
        // 添加动画样式
        this.addNotificationStyles();
        
        document.body.appendChild(notification);
        
        setTimeout(() => {
            if (notification.parentNode) {
                notification.parentNode.removeChild(notification);
            }
        }, duration);
    },

    /**
     * 将十六进制颜色转换为RGB
     * @param {string} hex 
     * @returns {string}
     */
    hexToRgb(hex) {
        const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
        return result ? 
            `${parseInt(result[1], 16)}, ${parseInt(result[2], 16)}, ${parseInt(result[3], 16)}` :
            '255, 255, 255';
    },

    /**
     * 添加通知动画样式
     */
    addNotificationStyles() {
        if (document.getElementById('notification-styles')) return;
        
        const style = document.createElement('style');
        style.id = 'notification-styles';
        style.textContent = `
            @keyframes notificationFadeInOut {
                0% { opacity: 0; transform: translate(-50%, -50%) scale(0.5); }
                20% { opacity: 1; transform: translate(-50%, -50%) scale(1.1); }
                80% { opacity: 1; transform: translate(-50%, -50%) scale(1); }
                100% { opacity: 0; transform: translate(-50%, -50%) scale(0.8); }
            }
        `;
        document.head.appendChild(style);
    }
};

/**
 * 本地存储工具函数
 */
export const StorageUtils = {
    /**
     * 保存游戏数据
     * @param {string} key 
     * @param {any} data 
     */
    save(key, data) {
        try {
            localStorage.setItem(key, JSON.stringify(data));
            return true;
        } catch (error) {
            console.error('保存数据失败:', error);
            return false;
        }
    },

    /**
     * 加载游戏数据
     * @param {string} key 
     * @param {any} defaultValue 
     * @returns {any}
     */
    load(key, defaultValue = null) {
        try {
            const data = localStorage.getItem(key);
            return data ? JSON.parse(data) : defaultValue;
        } catch (error) {
            console.error('加载数据失败:', error);
            return defaultValue;
        }
    },

    /**
     * 删除游戏数据
     * @param {string} key 
     */
    remove(key) {
        try {
            localStorage.removeItem(key);
            return true;
        } catch (error) {
            console.error('删除数据失败:', error);
            return false;
        }
    },

    /**
     * 清空所有游戏数据
     */
    clear() {
        try {
            localStorage.clear();
            return true;
        } catch (error) {
            console.error('清空数据失败:', error);
            return false;
        }
    }
};

/**
 * 性能监控工具
 */
export const PerformanceUtils = {
    /**
     * FPS计数器
     */
    fpsCounter: {
        fps: 0,
        frameCount: 0,
        lastTime: 0,
        
        update(currentTime) {
            this.frameCount++;
            if (currentTime - this.lastTime >= 1000) {
                this.fps = this.frameCount;
                this.frameCount = 0;
                this.lastTime = currentTime;
                
                // 更新FPS显示
                const fpsElement = DOMUtils.getElement('#fps-counter');
                if (fpsElement) {
                    fpsElement.textContent = this.fps;
                }
            }
        }
    },

    /**
     * 性能计时器
     * @param {string} label 
     * @param {function} fn 
     * @returns {any}
     */
    measure(label, fn) {
        const start = performance.now();
        const result = fn();
        const end = performance.now();
        console.log(`${label}: ${(end - start).toFixed(2)}ms`);
        return result;
    },

    /**
     * 内存使用监控
     */
    checkMemoryUsage() {
        if (performance.memory) {
            return {
                used: Math.round(performance.memory.usedJSHeapSize / 1048576),
                total: Math.round(performance.memory.totalJSHeapSize / 1048576),
                limit: Math.round(performance.memory.jsHeapSizeLimit / 1048576)
            };
        }
        return null;
    }
};

/**
 * 调试工具
 */
export const DebugUtils = {
    /**
     * 调试日志
     * @param {string} message 
     * @param {any} data 
     */
    log(message, data = null) {
        if (window.GAME_CONFIG?.GAME?.DEBUG_MODE) {
            if (data) {
                console.log(`[DEBUG] ${message}:`, data);
            } else {
                console.log(`[DEBUG] ${message}`);
            }
        }
    },

    /**
     * 错误日志
     * @param {string} message 
     * @param {Error} error 
     */
    error(message, error = null) {
        console.error(`[ERROR] ${message}`, error || '');
    },

    /**
     * 警告日志
     * @param {string} message 
     * @param {any} data 
     */
    warn(message, data = null) {
        console.warn(`[WARN] ${message}`, data || '');
    }
};

/**
 * 输入验证工具
 */
export const ValidationUtils = {
    /**
     * 验证是否为有效数字
     * @param {any} value 
     * @returns {boolean}
     */
    isValidNumber(value) {
        return typeof value === 'number' && !isNaN(value) && isFinite(value);
    },

    /**
     * 验证是否为有效字符串
     * @param {any} value 
     * @returns {boolean}
     */
    isValidString(value) {
        return typeof value === 'string' && value.length > 0;
    },

    /**
     * 验证是否为有效对象
     * @param {any} value 
     * @returns {boolean}
     */
    isValidObject(value) {
        return typeof value === 'object' && value !== null && !Array.isArray(value);
    },

    /**
     * 验证是否为有效数组
     * @param {any} value 
     * @returns {boolean}
     */
    isValidArray(value) {
        return Array.isArray(value);
    }
};

// 导出所有工具函数
export default {
    MathUtils,
    DOMUtils,
    GameUtils,
    AnimationUtils,
    NotificationUtils,
    StorageUtils,
    PerformanceUtils,
    DebugUtils,
    ValidationUtils
};

